/*
 * @Author: hongbin
 * @Date: 2022-11-19 20:35:52
 * @LastEditors: hongbin
 * @LastEditTime: 2022-12-24 21:03:55
 * @Description:
 */
import { createContext, useContext, useState, useEffect, useCallback, useMemo, useRef } from "react";
import { get } from "../api";
import { UserInfo } from "../hook/useRegisterForm";
import { SocketManager } from "../socket";
//! Next 无法获取localStorage 和window 等全局对象
// const jsonAuth = Auth.getLocalUser_Info();
// const localAuth = jsonAuth ? JSON.parse(jsonAuth) : undefined;

interface IContext {
    isLogin: boolean;
    user: Partial<UserInfo>;
    signOut: () => void;
    recordUserInformation: (userInfo: Partial<UserInfo>) => void;
}

const Context = createContext({} as IContext);

const AuthProvide = ({ children }: { children: JSX.Element }): JSX.Element => {
    const [user, setUser] = useState({} as IContext["user"]);
    const isLogin = useMemo(() => !!user.name, [user]);

    /**
     * 验证登录信息是否过期 本地有则免登陆
     */
    const initAuth = useCallback(async () => {
        //用本地jwt去服务端验证 若成功则和localStorage的比较 不同则替换 失败则执行退出操作
        const localUserInfo = JSON.parse(localStorage.getItem("userInfo") || "{}");
        console.log("本地用户数据:", localUserInfo);
        setUser(localUserInfo);
        if (localUserInfo._id) {
            //拉取新数据 好友添加可以在离线时完成 登录时获取新的信息
            get("/Auth/queryUserById?id=" + localUserInfo._id).then((d) => {
                if (d.data && d.data._id) {
                    setUser(d.data);
                }
            });
        }
    }, []);

    useEffect(() => {
        initAuth();
    }, [initAuth]);

    /**
     * 保存本地数据 放在initAuth后执行否则先执行讲本地数据置为{}
     */
    useEffect(() => {
        // console.log("user变更:", user, prevUser.current);
        localStorage.setItem("userInfo", JSON.stringify(user));
        if (user._id) {
            SocketManager.emit("setSocketId", user._id);
        }
    }, [user]);
    /**
     * 登出
     */
    const signOut = useCallback(() => {
        setUser((prev) => {
            if (prev._id) {
                SocketManager.emit("signOut", prev._id);
            }
            return {};
        });
    }, []);

    /**
     * 记录用户信息状态
     */
    const recordUserInformation: IContext["recordUserInformation"] = useCallback((userInfo) => {
        setUser(userInfo);
        if (userInfo._id) SocketManager.emit("setSocketId", userInfo._id);
    }, []);

    return <Context.Provider value={{ isLogin, user, signOut, recordUserInformation }}>{children}</Context.Provider>;
};

export const useAuth = () => useContext(Context);

export default AuthProvide;
